Virtual Proxy

nullptr이나 초기화 되지 않은 포인터를 역참조하게 되면, 크래시가 발생한다.
느긋한 인스턴스화(객체를 생성하되, 불필요하게 자원을 일찍 할당되는 것을 원하지 않는 경우)를 하기 위해
버추얼 프록시를 이용해 실제 인스턴스에 접근하는 대신 가상의 객체에 접근하도록 할 수 있다.
struct Image{
virtual void draw()=0;
}
// ( )
struct Bitmap: Image{
Bitmap(const string& filename){
cout<<"Loading image from "<<filename<<endl;
}
void draw() override {
cout<<"Drawing image "<<filename<<endl;
}
};
//( )
Bitmap img{"pokemon.png"};
위에서 Bitmap이 외부에서 제공하는 라이브러리여서 직접 코드를 수정할 수 없다고 하자
이와 같은 상황에서 가상 프록시를 활용해서, Bitmap과 동일한 인터페이스를 제공하고
Bitmap 기능을 활용하되 동작 방식을 수정할 수 있다.
struct LazyBitmap: Image{
LazyBitmap(const string& filename): filename(filename) {}
~LazyBitmap(){ delete bmp; }
void draw() override{
if(!bmp) bmp=new Bitmap(filename);
bmp->draw();
}
private:
Bitmap* bmp{nullptr};
string filename;
};
// Bitmap draw_image
void draw_image(Image& img){
cout<<"About to draw the image"<<endl;
img.draw();
cout<<"Done drawing the image"<<endl;
}
// ( , )
LazyBitmap img{"pokemon.png"};
draw_image(img);
위의 LazyBitmap 클래스의 생성자는 Bitmap 생성자보다 훨씬 가볍다.
그림 파일의 이름을 별도로 저장하고, 실제 파일 로딩 작업은 draw() 가 호출될 때까지 미룬다.